/*
    DIMVisual-KAAPI, the DIMVisual bundle for KAAPI trace files
    Copyright (c) 2008 Lucas Mello Schnorr <schnorr@gmail.com>

    This file is part of DIMVisual-KAAPI.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "KAAPIParser.h"
#include "KAAPIRecordReaderObjc.h"
#include <GenericEvent/GEvent.h>

@implementation KAAPIParser (Util)
- (GEvent *) threadName: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GIdentifier *nameid;
	GFields *fields;
	EVT_UTIL_THREAD_NAME_Record *threadname;

	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];
	nameid = [[GIdentifier alloc] init];
	threadname = (EVT_UTIL_THREAD_NAME_Record *)r;

	[nameid addValue: [NSString stringWithFormat: @"name"]];
	[fields setFieldWithKey: nameid withValue: [NSString stringWithFormat: @"%d", threadname->name]];
//	NSLog (@"# %d -> %d", (int)r->_cid, (int)threadname->name);

	[name setName: @"EVT_UTIL_THREAD_NAME"];
	[ev setName: name];	
	[ev setFields: fields];

	[name release];
	[fields release];
	[nameid release];

	[ev autorelease];
	return ev;
}

- (GEvent *) threadStart: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GIdentifier *contextid;
	GFields *fields;
	EVT_UTIL_THREAD_START_Record *threadstart;

	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];
	contextid = [[GIdentifier alloc] init];
	threadstart = (EVT_UTIL_THREAD_START_Record *)r;

	char str[100];
	snprintf (str, 100, "%d", (unsigned int)threadstart->cid);

	[contextid addValue: [NSString stringWithFormat: @"cid"]];
	[fields setFieldWithKey: contextid withValue: [NSString stringWithFormat: @"%s", str]];

	[name setName: @"EVT_UTIL_THREAD_START"];
	[ev setName: name];	
	[ev setFields: fields];

	[contextid release];
	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}

- (GEvent *) threadRun: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GFields *fields;
	EVT_UTIL_THREAD_RUN_Record *threadrun;

	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];
	threadrun = (EVT_UTIL_THREAD_RUN_Record *)r;

	[name setName: @"EVT_UTIL_THREAD_RUN"];
	[ev setName: name];	
	[ev setFields: fields];
	
	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}

- (GEvent *) threadTerm: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GFields *fields;
	EVT_UTIL_THREAD_TERM_Record *threadterm;

	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];
	threadterm = (EVT_UTIL_THREAD_TERM_Record *)r;

	[name setName: @"EVT_UTIL_THREAD_TERM"];
	[ev setName: name];	
	[ev setFields: fields];
	
	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}

- (GEvent *) utilProcessBlocName: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GFields *fields;
	EVT_UTIL_PROCESS_BLOC_NAME_Record *revent;
	
	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];

	revent = (EVT_UTIL_PROCESS_BLOC_NAME_Record *) r;


	[name setName: @"EVT_UTIL_PROCESS_BLOC_NAME"];
	[ev setName: name];	
	[ev setFields: fields];

	[fields setFieldWithStringKey: @"name" withValue:
                [NSString stringWithFormat: @"%s", revent->name.name]];

	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}


- (GEvent *) utilProcessName: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GFields *fields;
	EVT_UTIL_PROCESS_NAME_Record *revent;
	revent = (EVT_UTIL_PROCESS_NAME_Record *) r;
	
	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];

	[name setName: @"EVT_UTIL_PROCESS_NAME"];
	[ev setName: name];	
	[ev setFields: fields];


	[fields setFieldWithStringKey: @"csize" withValue: [NSString stringWithFormat: @"%d", (int)revent->csize]];

	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}

- (GEvent *) utilProcessInfo: (Util::Record *) r
{
	GEvent *ev;
	GName *name;
	GFields *fields;
	EVT_UTIL_PROCESS_INFO_Record *revent;
	revent = (EVT_UTIL_PROCESS_INFO_Record *) r;
	
	ev = [[GEvent alloc] init];
	name = [[GName alloc] init]; 
	fields = [[GFields alloc] init];

	[name setName: @"EVT_UTIL_PROCESS_INFO"];
	[ev setName: name];
	[ev setFields: fields];


	[fields setFieldWithStringKey: @"tick_per_s" withValue: [NSString stringWithFormat: @"%f", (double)revent->tick_per_s]];
	[fields setFieldWithStringKey: @"timeofday" withValue: [NSString stringWithFormat: @"%f", (double)revent->timeofday]];

	[name release];
	[fields release];

	[ev autorelease];
	return ev;
}



- (GEvent *) parseKAAPIUtilLevel: (Util::Record *) r
	withIdentifier: (GIdentifier *) identifier
	withTimestamp: (GTimestamp *) timestamp
{
	GEvent *ev = nil;
	switch (r->_event){
		case Event::UTIL_THREAD_NAME:
			ev = [self threadName: r];
			break;
		case Event::UTIL_THREAD_START:
			ev = [self threadStart: r];
			break;
		case Event::UTIL_THREAD_RUN:
			ev = [self threadRun: r];
			break;
		case Event::UTIL_THREAD_TERM:
			ev = [self threadTerm: r];
			break;
		case Event::UTIL_THREAD_YIELDTO:
			ev = [self generic: r];
			break;
		case Event::UTIL_THREAD_RESUME:
			ev = [self generic: r];
			break;
		case Event::UTIL_PROCESS_NAME:
			ev = [self utilProcessName: r];
			break;
		case Event::UTIL_PROCESS_BLOC_NAME:
			ev = [self utilProcessBlocName: r];
			break;
		case Event::UTIL_PROCESS_INFO:
			ev = [self utilProcessInfo: r];
			break;
		default:
			NSLog (@"Warning: Util_Level -> type = %d, not completely translated", r->_event);
			break;
	}
	if (ev != nil){
		[ev setTimestamp: timestamp];
		[ev setIdentifier: identifier];
	}
	return ev; //already autoreleased
}

@end
